//实现语音识别子服务
#include <brpc/server.h>
#include <butil/logging.h>

#include "data_es.hpp"      // es数据管理客户端封装
#include "mysql_chat_session_member.hpp"      // mysql数据管理客户端封装
#include "mysql_chat_session.hpp"      // mysql数据管理客户端封装
#include "mysql_relation.hpp"      // mysql数据管理客户端封装
#include "mysql_apply.hpp"      // mysql数据管理客户端封装
#include "etcd.hpp"     // 服务注册模块封装
#include "logger.hpp"   // 日志模块封装
#include "utils.hpp"    // 基础工具接口
#include "channel.hpp"  // 信道管理模块封装


#include "friend.pb.h"  // protobuf框架代码
#include "base.pb.h"  // protobuf框架代码
#include "user.pb.h"  // protobuf框架代码
#include "message.pb.h"  // protobuf框架代码

namespace mag{
class FriendServiceImpl : public mag::FriendService {
    public:
        FriendServiceImpl(
            const std::shared_ptr<elasticlient::Client> &es_client,
            const std::shared_ptr<odb::core::database> &mysql_client,
            const ServiceManager::ptr &channel_manager,
            const std::string &user_service_name,
            const std::string &message_service_name) :
            _es_user(std::make_shared<ESUser>(es_client)),
            _mysql_apply(std::make_shared<FriendApplyTable>(mysql_client)),
            _mysql_chat_session(std::make_shared<ChatSessionTable>(mysql_client)),
            _mysql_chat_session_member(std::make_shared<ChatSessionMemeberTable>(mysql_client)),
            _mysql_relation(std::make_shared<RelationTable>(mysql_client)),
            _user_service_name(user_service_name),
            _message_service_name(message_service_name),
            _mm_channels(channel_manager){}
        ~FriendServiceImpl(){}
        virtual void GetFriendList(::google::protobuf::RpcController* controller,
            const ::mag::GetFriendListReq* request,
            ::mag::GetFriendListRsp* response,
            ::google::protobuf::Closure* done) {
            brpc::ClosureGuard rpc_guard(done);
            //1. 定义错误回调
            auto err_response = [this, response](const std::string &rid, 
                const std::string &errmsg) -> void {
                response->set_request_id(rid);
                response->set_success(false);
                response->set_errmsg(errmsg);
                return;
            };
            
            //1. 提取请求中的关键要素：用户ID
            std::string rid = request->request_id();
            std::string uid = request->user_id();
            //2. 从数据库中查询获取用户的好友ID
            auto friend_id_lists = _mysql_relation->friends(uid);
            std::unordered_set<std::string> user_id_lists;
            for (auto &id : friend_id_lists) {
                user_id_lists.insert(id);
            }
            //3. 从用户子服务批量获取用户信息
            std::unordered_map<std::string, UserInfo> user_list;
            bool ret = GetUserInfo(rid, user_id_lists, user_list);
            if (ret == false) {
                LOG_ERROR("{} - 批量获取用户信息失败!", rid);
                return err_response(rid, "批量获取用户信息失败!");
            }
            //4. 组织响应
            response->set_request_id(rid);
            response->set_success(true);
            for (const auto & user_it : user_list) {
                auto user_info = response->add_friend_list();
                user_info->CopyFrom(user_it.second);
            }
        }
        virtual void FriendRemove(::google::protobuf::RpcController* controller,
            const ::mag::FriendRemoveReq* request,
            ::mag::FriendRemoveRsp* response,
            ::google::protobuf::Closure* done) {
            brpc::ClosureGuard rpc_guard(done);
            //1. 定义错误回调
            auto err_response = [this, response](const std::string &rid, 
                const std::string &errmsg) -> void {
                response->set_request_id(rid);
                response->set_success(false);
                response->set_errmsg(errmsg);
                return;
            };
            //1. 提取关键要素：当前用户ID，要删除的好友ID
            std::string rid = request->request_id();
            std::string uid = request->user_id();
            std::string pid = request->peer_id();
            //2. 从好友关系表中删除好友关系信息
            bool ret = _mysql_relation->remove(uid, pid);
            if (ret == false) {
                LOG_ERROR("{} - 从数据库删除好友信息失败！", rid);
                return err_response(rid, "从数据库删除好友信息失败！");
            }
            //3. 从会话信息表中，删除对应的聊天会话 -- 同时删除会话成员表中的成员信息
            ret = _mysql_chat_session->remove(uid, pid);
            if (ret == false) {
                LOG_ERROR("{}- 从数据库删除好友会话信息失败！", rid);
                return err_response(rid, "从数据库删除好友会话信息失败！");
            }
            //4. 组织响应
            response->set_request_id(rid);
            response->set_success(true);
        }
        virtual void FriendAdd(::google::protobuf::RpcController* controller,
            const ::mag::FriendAddReq* request,
            ::mag::FriendAddRsp* response,
            ::google::protobuf::Closure* done) {
            brpc::ClosureGuard rpc_guard(done);
            //1. 定义错误回调
            auto err_response = [this, response](const std::string &rid, 
                const std::string &errmsg) -> void {
                response->set_request_id(rid);
                response->set_success(false);
                response->set_errmsg(errmsg);
                return;
            };
            //1. 提取请求中的关键要素：申请人用户ID； 被申请人用户ID
            std::string rid = request->request_id();
            std::string uid = request->user_id();
            std::string pid = request->respondent_id();
            //2. 判断两人是否已经是好友
            bool ret = _mysql_relation->exists(uid, pid);
            if (ret == true) {
                LOG_ERROR("{}- 申请好友失败-两者{}-{}已经是好友关系", rid, uid, pid);
                return err_response(rid, "两者已经是好友关系！");
            }
            //3. 当前是否已经申请过好友
            ret = _mysql_apply->exists(uid, pid);
            if (ret == true) {
                LOG_ERROR("{}- 申请好友失败-已经申请过对方好友！", rid, uid, pid);
                return err_response(rid, "已经申请过对方好友！");
            }
            //4. 向好友申请表中，新增申请信息
            std::string eid = uuid();
            FriendApply ev(eid, uid, pid);
            ret = _mysql_apply->insert(ev);
            if (ret == false) {
                LOG_ERROR("{} - 向数据库新增好友申请事件失败！", rid);
                return err_response(rid, "向数据库新增好友申请事件失败！");
            }
            //3. 组织响应
            response->set_request_id(rid);
            response->set_success(true);
            response->set_notify_event_id(eid);
        }
        virtual void FriendAddProcess(::google::protobuf::RpcController* controller,
            const ::mag::FriendAddProcessReq* request,
            ::mag::FriendAddProcessRsp* response,
            ::google::protobuf::Closure* done) {
            brpc::ClosureGuard rpc_guard(done);
            //1. 定义错误回调
            auto err_response = [this, response](const std::string &rid, 
                const std::string &errmsg) -> void {
                response->set_request_id(rid);
                response->set_success(false);
                response->set_errmsg(errmsg);
                return;
            };
            //1. 提取请求中的关键要素：申请人用户ID；被申请人用户ID；处理结果；事件ID
            std::string rid = request->request_id();
            std::string eid = request->notify_event_id();
            std::string uid = request->user_id(); //被申请人
            std::string pid = request->apply_user_id();//申请人
            bool agree = request->agree();
            //2. 判断有没有该申请事件
            bool ret = _mysql_apply->exists(pid, uid);
            if (ret == false) {
                LOG_ERROR("{}- 没有找到{}-{}对应的好友申请事件！", rid, pid, uid);
                return err_response(rid, "没有找到对应的好友申请事件!");
            }
            //3. 如果有： 可以处理； --- 删除申请事件--事件已经处理完毕
            ret = _mysql_apply->remove(pid, uid);
            if (ret == false) {
                LOG_ERROR("{}- 从数据库删除申请事件 {}-{} 失败！", rid, pid, uid);
                return err_response(rid, "从数据库删除申请事件失败!");
            }
            //4. 如果处理结果是同意：向数据库新增好友关系信息；新增单聊会话信息及会话成员
            std::string cssid;
            if (agree == true) {
                ret = _mysql_relation->insert(uid, pid);
                if (ret == false) {
                    LOG_ERROR("{}- 新增好友关系信息-{}-{}！", rid, uid, pid);
                    return err_response(rid, "新增好友关系信息!");
                }
                cssid = uuid();
                ChatSession cs(cssid, "", ChatSessionType::SINGLE);
                ret = _mysql_chat_session->insert(cs);
                if (ret == false) {
                    LOG_ERROR("{}- 新增单聊会话信息-{}！", rid, cssid);
                    return err_response(rid, "新增单聊会话信息失败!");
                }
                ChatSessionMember csm1(cssid, uid);
                ChatSessionMember csm2(cssid, pid);
                std::vector<ChatSessionMember> mlist = {csm1, csm2};
                ret = _mysql_chat_session_member->append(mlist);
                if (ret == false) {
                    LOG_ERROR("{}- 没有找到{}-{}对应的好友申请事件！", rid, pid, uid);
                    return err_response(rid, "没有找到对应的好友申请事件!");
                }
            }
            //5. 组织响应
            response->set_request_id(rid);
            response->set_success(true);
            response->set_new_session_id(cssid);
        }
        virtual void FriendSearch(::google::protobuf::RpcController* controller,
            const ::mag::FriendSearchReq* request,
            ::mag::FriendSearchRsp* response,
            ::google::protobuf::Closure* done) {
            brpc::ClosureGuard rpc_guard(done);
            //1. 定义错误回调
            auto err_response = [this, response](const std::string &rid, 
                const std::string &errmsg) -> void {
                response->set_request_id(rid);
                response->set_success(false);
                response->set_errmsg(errmsg);
                return;
            };
            //1. 提取请求中的关键要素：搜索关键字（可能是用户ID，可能是手机号，可能是昵称的一部分）
            std::string rid = request->request_id();
            std::string uid = request->user_id();
            std::string skey = request->search_key();
            LOG_DEBUG("{} 好友搜索 ： {}", uid, skey);
            //2. 根据用户ID，获取用户的好友ID列表
            auto friend_id_lists = _mysql_relation->friends(uid);
            //3. 从ES搜索引擎进行用户信息搜索 --- 过滤掉当前的好友
            std::unordered_set<std::string> user_id_lists;
            friend_id_lists.push_back(uid);// 把自己也过滤掉
            auto search_res = _es_user->search(skey, friend_id_lists);
            for (auto &it : search_res) {
                user_id_lists.insert(it.user_id());
            }
            //4. 根据获取到的用户ID， 从用户子服务器进行批量用户信息获取
            std::unordered_map<std::string, UserInfo> user_list;
            bool ret = GetUserInfo(rid, user_id_lists, user_list);
            if (ret == false) {
                LOG_ERROR("{} - 批量获取用户信息失败!", rid);
                return err_response(rid, "批量获取用户信息失败!");
            }
            //5. 组织响应
            response->set_request_id(rid);
            response->set_success(true);
            for (const auto & user_it : user_list) {
                auto user_info = response->add_user_info();
                user_info->CopyFrom(user_it.second);
            }
        }
        virtual void GetPendingFriendEventList(::google::protobuf::RpcController* controller,
            const ::mag::GetPendingFriendEventListReq* request,
            ::mag::GetPendingFriendEventListRsp* response,
            ::google::protobuf::Closure* done) {
            brpc::ClosureGuard rpc_guard(done);
            //1. 定义错误回调
            auto err_response = [this, response](const std::string &rid, 
                const std::string &errmsg) -> void {
                response->set_request_id(rid);
                response->set_success(false);
                response->set_errmsg(errmsg);
                return;
            };
            //1. 提取关键要素：当前用户ID
            std::string rid = request->request_id();
            std::string uid = request->user_id();
            //2. 从数据库获取待处理的申请事件信息 --- 申请人用户ID列表
            auto res = _mysql_apply->applyUsers(uid);
            std::unordered_set<std::string> user_id_lists;
            for (auto &id : res) {
                user_id_lists.insert(id);
            }
            //3. 批量获取申请人用户信息、
            std::unordered_map<std::string, UserInfo> user_list;
            bool ret = GetUserInfo(rid, user_id_lists, user_list);
            if (ret == false) {
                LOG_ERROR("{} - 批量获取用户信息失败!", rid);
                return err_response(rid, "批量获取用户信息失败!");
            }
            //4. 组织响应
            response->set_request_id(rid);
            response->set_success(true);
            for (const auto & user_it : user_list) {
                auto ev = response->add_event();
                ev->mutable_sender()->CopyFrom(user_it.second);
            }
        }
        virtual void GetChatSessionList(::google::protobuf::RpcController* controller,
            const ::mag::GetChatSessionListReq* request,
            ::mag::GetChatSessionListRsp* response,
            ::google::protobuf::Closure* done) {
            brpc::ClosureGuard rpc_guard(done);
            //1. 定义错误回调
            auto err_response = [this, response](const std::string &rid, 
                const std::string &errmsg) -> void {
                response->set_request_id(rid);
                response->set_success(false);
                response->set_errmsg(errmsg);
                return;
            };
            //获取聊天会话的作用：一个用户登录成功后，能够展示自己的历史聊天信息
            //1. 提取请求中的关键要素：当前请求用户ID
            std::string rid = request->request_id();
            std::string uid = request->user_id();
            //2. 从数据库中查询出用户的单聊会话列表
            auto sf_list = _mysql_chat_session->singleChatSession(uid);
            //  1. 从单聊会话列表中，取出所有的好友ID，从用户子服务获取用户信息
            std::unordered_set<std::string> users_id_list;
            for (const auto &f : sf_list) {
                users_id_list.insert(f.friend_id);
            }
            std::unordered_map<std::string, UserInfo> user_list;
            bool ret = GetUserInfo(rid, users_id_list, user_list);
            if (ret == false) {
                LOG_ERROR("{} - 批量获取用户信息失败！", rid);
                return err_response(rid, "批量获取用户信息失败!");
            }
            //  2. 设置响应会话信息：会话名称就是好友名称；会话头像就是好友头像
            //3. 从数据库中查询出用户的群聊会话列表
            auto gc_list = _mysql_chat_session->groupChatSession(uid);

            //4. 根据所有的会话ID，从消息存储子服务获取会话最后一条消息
            //5. 组织响应
            for (const auto &f : sf_list) {
                auto chat_session_info = response->add_chat_session_info_list();
                chat_session_info->set_single_chat_friend_id(f.friend_id);
                chat_session_info->set_chat_session_id(f.chat_session_id);
                chat_session_info->set_chat_session_name(user_list[f.friend_id].nickname());
                chat_session_info->set_avatar(user_list[f.friend_id].avatar());
                MessageInfo msg;
                ret = GetRecentMsg(rid, f.chat_session_id, msg);
                if (ret == false) {continue;}
                chat_session_info->mutable_prev_message()->CopyFrom(msg);
            }
            for (const auto &f : gc_list) {
                auto chat_session_info = response->add_chat_session_info_list();
                chat_session_info->set_chat_session_id(f.chat_session_id);
                chat_session_info->set_chat_session_name(f.chat_session_name);
                MessageInfo msg;
                ret = GetRecentMsg(rid, f.chat_session_id, msg);
                if (ret == false) { continue; }
                chat_session_info->mutable_prev_message()->CopyFrom(msg);
            }
            response->set_request_id(rid);
            response->set_success(true);
        }
        virtual void ChatSessionCreate(::google::protobuf::RpcController* controller,
            const ::mag::ChatSessionCreateReq* request,
            ::mag::ChatSessionCreateRsp* response,
            ::google::protobuf::Closure* done) {
            brpc::ClosureGuard rpc_guard(done);
            //1. 定义错误回调
            auto err_response = [this, response](const std::string &rid, 
                const std::string &errmsg) -> void {
                response->set_request_id(rid);
                response->set_success(false);
                response->set_errmsg(errmsg);
                return;
            };
            //创建会话，其实针对的是用户要创建一个群聊会话
            //1. 提取请求关键要素：会话名称，会话成员
            std::string rid = request->request_id();
            std::string uid = request->user_id();
            std::string cssname = request->chat_session_name();
            
            //2. 生成会话ID，向数据库添加会话信息，添加会话成员信息
            std::string cssid = uuid();
            ChatSession cs(cssid, cssname, ChatSessionType::GROUP);
            bool ret = _mysql_chat_session->insert(cs);
            if (ret == false) {
                LOG_ERROR("{} - 向数据库添加会话信息失败: {}", rid, cssname);
                return err_response(rid, "向数据库添加会话信息失败!");
            }
            std::vector<ChatSessionMember> member_list;
            for (int i = 0; i < request->member_id_list_size(); i++) {
                ChatSessionMember csm(cssid, request->member_id_list(i));
                member_list.push_back(csm);
            }
            ret = _mysql_chat_session_member->append(member_list);
            if (ret == false) {
                LOG_ERROR("{} - 向数据库添加会话成员信息失败: {}", rid, cssname);
                return err_response(rid, "向数据库添加会话成员信息失败!");
            }
            //3. 组织响应---组织会话信息
            response->set_request_id(rid);
            response->set_success(true);
            response->mutable_chat_session_info()->set_chat_session_id(cssid);
            response->mutable_chat_session_info()->set_chat_session_name(cssname);
        }
        virtual void GetChatSessionMember(::google::protobuf::RpcController* controller,
            const ::mag::GetChatSessionMemberReq* request,
            ::mag::GetChatSessionMemberRsp* response,
            ::google::protobuf::Closure* done) {
            brpc::ClosureGuard rpc_guard(done);
            //1. 定义错误回调
            auto err_response = [this, response](const std::string &rid, 
                const std::string &errmsg) -> void {
                response->set_request_id(rid);
                response->set_success(false);
                response->set_errmsg(errmsg);
                return;
            };
            //用于用户查看群聊成员信息的时候：进行成员信息展示
            //1. 提取关键要素：聊天会话ID
            std::string rid = request->request_id();
            std::string uid = request->user_id();
            std::string cssid = request->chat_session_id();
            //2. 从数据库获取会话成员ID列表
            auto member_id_lists = _mysql_chat_session_member->members(cssid);
            std::unordered_set<std::string> uid_list;
            for (const auto &id : member_id_lists) {
                uid_list.insert(id);
            }
            //3. 从用户子服务批量获取用户信息
            std::unordered_map<std::string, UserInfo> user_list;
            bool ret = GetUserInfo(rid, uid_list, user_list);
            if (ret == false) {
                LOG_ERROR("{} - 从用户子服务获取用户信息失败！", rid);
                return err_response(rid, "从用户子服务获取用户信息失败!");
            }
            //4. 组织响应
            response->set_request_id(rid);
            response->set_success(true);
            for (const auto &uit : user_list) {
                auto user_info = response->add_member_info_list();
                user_info->CopyFrom(uit.second);
            }
        }
    private:
        bool GetRecentMsg(const std::string &rid, 
            const std::string &cssid, MessageInfo &msg) {
            auto channel = _mm_channels->choose(_message_service_name);
            if (!channel) {
                LOG_ERROR("{} - 获取消息子服务信道失败！！", rid);
                return false;
            }
            GetRecentMsgReq req;
            GetRecentMsgRsp rsp;
            req.set_request_id(rid);
            req.set_chat_session_id(cssid);
            req.set_msg_count(1);
            brpc::Controller cntl;
            mag::MsgStorageService_Stub stub(channel.get());
            stub.GetRecentMsg(&cntl, &req, &rsp, nullptr);
            if (cntl.Failed() == true) {
                LOG_ERROR("{} - 消息存储子服务调用失败: {}", rid, cntl.ErrorText());
                return false;
            }
            if ( rsp.success() == false) {
                LOG_ERROR("{} - 获取会话 {} 最近消息失败: {}", rid, cssid, rsp.errmsg());
                return false;
            }
            if (rsp.msg_list_size() > 0) {
                msg.CopyFrom(rsp.msg_list(0));
                return true;
            }
            return false;
        }
        bool GetUserInfo(const std::string &rid, 
            const std::unordered_set<std::string> &uid_list,
            std::unordered_map<std::string, UserInfo> &user_list) {
            auto channel = _mm_channels->choose(_user_service_name);
            if (!channel) {
                LOG_ERROR("{} - 获取用户子服务信道失败！！", rid);
                return false;
            }
            GetMultiUserInfoReq req;
            GetMultiUserInfoRsp rsp;
            req.set_request_id(rid);
            for (auto &id : uid_list) {
                req.add_users_id(id);
            }
            brpc::Controller cntl;
            mag::UserService_Stub stub(channel.get());
            stub.GetMultiUserInfo(&cntl, &req, &rsp, nullptr);
            if (cntl.Failed() == true) {
                LOG_ERROR("{} - 用户子服务调用失败: {}", rid, cntl.ErrorText());
                return false;
            }
            if ( rsp.success() == false) {
                LOG_ERROR("{} - 批量获取用户信息失败: {}", rid, rsp.errmsg());
                return false;
            }
            for (const auto & user_it : rsp.users_info()) {
                user_list.insert(std::make_pair(user_it.first, user_it.second));
            }
            return true;
        }

    private:
        ESUser::ptr _es_user;

        FriendApplyTable::ptr _mysql_apply;
        ChatSessionTable::ptr _mysql_chat_session;
        ChatSessionMemeberTable::ptr _mysql_chat_session_member;
        RelationTable::ptr _mysql_relation;

        //这边是rpc调用客户端相关对象
        std::string _user_service_name;
        std::string _message_service_name;
        ServiceManager::ptr _mm_channels;
};

class FriendServer {
    public:
        using ptr = std::shared_ptr<FriendServer>;
        FriendServer(const Discovery::ptr service_discoverer, 
            const Registry::ptr &reg_client,
            const std::shared_ptr<elasticlient::Client> &es_client,
            const std::shared_ptr<odb::core::database> &mysql_client,
            const std::shared_ptr<brpc::Server> &server):
            _service_discoverer(service_discoverer),
            _registry_client(reg_client),
            _es_client(es_client),
            _mysql_client(mysql_client),
            _rpc_server(server){}
        ~FriendServer(){}
        //搭建RPC服务器，并启动服务器
        void start() {
            _rpc_server->RunUntilAskedToQuit();
        }
    private:
        Discovery::ptr _service_discoverer;
        Registry::ptr _registry_client;
        std::shared_ptr<elasticlient::Client> _es_client;
        std::shared_ptr<odb::core::database> _mysql_client;
        std::shared_ptr<brpc::Server> _rpc_server;
};

class FriendServerBuilder {
    public:
        //构造es客户端对象
        void make_es_object(const std::vector<std::string> host_list) {
            _es_client = ESClientFactory::create(host_list);
        }
        //构造mysql客户端对象
        void make_mysql_object(
            const std::string &user,
            const std::string &pswd,
            const std::string &host,
            const std::string &db,
            const std::string &cset,
            int port,
            int conn_pool_count) {
            _mysql_client = ODBFactory::create(user, pswd, host, db, cset, port, conn_pool_count);
        }
        //用于构造服务发现客户端&信道管理对象
        void make_discovery_object(const std::string &reg_host,
            const std::string &base_service_name,
            const std::string &user_service_name,
            const std::string &message_service_name) {
            _user_service_name = user_service_name;
            _message_service_name = message_service_name;
            _mm_channels = std::make_shared<ServiceManager>();
            _mm_channels->declared(user_service_name);
            _mm_channels->declared(message_service_name);
            LOG_DEBUG("设置用户子服务为需添加管理的子服务：{}", user_service_name);
            LOG_DEBUG("设置消息子服务为需添加管理的子服务：{}", message_service_name);
            auto put_cb = std::bind(&ServiceManager::onServiceOnline, _mm_channels.get(), std::placeholders::_1, std::placeholders::_2);
            auto del_cb = std::bind(&ServiceManager::onServiceOffline, _mm_channels.get(), std::placeholders::_1, std::placeholders::_2);
            _service_discoverer = std::make_shared<Discovery>(reg_host, base_service_name, put_cb, del_cb);
        }
        //用于构造服务注册客户端对象
        void make_registry_object(const std::string &reg_host,
            const std::string &service_name,
            const std::string &access_host) {
            _registry_client = std::make_shared<Registry>(reg_host);
            _registry_client->registry(service_name, access_host);
        }
        void make_rpc_server(uint16_t port, int32_t timeout, uint8_t num_threads) {
            if (!_es_client) {
                LOG_ERROR("还未初始化ES搜索引擎模块！");
                abort();
            }
            if (!_mysql_client) {
                LOG_ERROR("还未初始化Mysql数据库模块！");
                abort();
            }
            if (!_mm_channels) {
                LOG_ERROR("还未初始化信道管理模块！");
                abort();
            }
            _rpc_server = std::make_shared<brpc::Server>();

            FriendServiceImpl *friend_service = new FriendServiceImpl(_es_client,
                _mysql_client, _mm_channels, _user_service_name, _message_service_name);
            int ret = _rpc_server->AddService(friend_service, 
                brpc::ServiceOwnership::SERVER_OWNS_SERVICE);
            if (ret == -1) {
                LOG_ERROR("添加Rpc服务失败！");
                abort();
            }
            brpc::ServerOptions options;
            options.idle_timeout_sec = timeout;
            options.num_threads = num_threads;
            ret = _rpc_server->Start(port, &options);
            if (ret == -1) {
                LOG_ERROR("服务启动失败！");
                abort();
            }
        }
        //构造RPC服务器对象
        FriendServer::ptr build() {
            if (!_service_discoverer) {
                LOG_ERROR("还未初始化服务发现模块！");
                abort();
            }
            if (!_registry_client) {
                LOG_ERROR("还未初始化服务注册模块！");
                abort();
            }
            if (!_rpc_server) {
                LOG_ERROR("还未初始化RPC服务器模块！");
                abort();
            }
            FriendServer::ptr server = std::make_shared<FriendServer>(
                _service_discoverer, _registry_client,
                _es_client, _mysql_client, _rpc_server);
            return server;
        }
    private:
        Registry::ptr _registry_client;

        std::shared_ptr<elasticlient::Client> _es_client;
        std::shared_ptr<odb::core::database> _mysql_client;

        std::string _user_service_name;
        std::string _message_service_name;
        ServiceManager::ptr _mm_channels;
        Discovery::ptr _service_discoverer;

        std::shared_ptr<brpc::Server> _rpc_server;
};
}

// // 实现好友管理子服务
// #include <brpc/server.h>
// #include <butil/logging.h>

// #include "data_es.hpp"                      // ES数据管理客户端封装
// #include "mysql_chat_session_member.hpp"    // MySQL数据管理客户端封装
// #include "mysql_chat_session.hpp"           // MySQL数据管理客户端封装
// #include "mysql_relation.hpp"               // MySQL数据管理客户端封装
// #include "mysql_apply.hpp"                  // MySQL数据管理客户端封装
// #include "etcd.hpp"                         // 服务注册模块封装
// #include "logger.hpp"                       // 日志模块封装
// #include "utils.hpp"                        // 基础工具接口
// #include "channel.hpp"                      // 信道管理模块封装

// #include "friend.pb.h"                      // protobuf框架代码
// #include "base.pb.h"                        // protobuf框架代码
// #include "user.pb.h"                        // protobuf框架代码
// #include "message.pb.h"                     // protobuf框架代码

// namespace mag { // 修改命名空间为 mag

//     /**
//      * @brief FriendServiceImpl 实现了好友服务的具体逻辑
//      */
//     class FriendServiceImpl : public mag::FriendService {
//     public:
//         /**
//          * @brief 构造函数，初始化各个子模块
//          * 
//          * @param es_client ES客户端
//          * @param mysql_client MySQL数据库客户端
//          * @param channel_manager 信道管理器
//          * @param user_service_name 用户子服务名称
//          * @param message_service_name 消息子服务名称
//          */
//         FriendServiceImpl(
//             const std::shared_ptr<elasticlient::Client> &es_client,
//             const std::shared_ptr<odb::core::database> &mysql_client,
//             const ServiceManager::ptr &channel_manager,
//             const std::string &user_service_name,
//             const std::string &message_service_name) :
//             _es_user(std::make_shared<ESUser>(es_client)),
//             _mysql_apply(std::make_shared<FriendApplyTable>(mysql_client)),
//             _mysql_chat_session(std::make_shared<ChatSessionTable>(mysql_client)),
//             _mysql_chat_session_member(std::make_shared<ChatSessionMemeberTable>(mysql_client)),
//             _mysql_relation(std::make_shared<RelationTable>(mysql_client)),
//             _user_service_name(user_service_name),
//             _message_service_name(message_service_name),
//             _mm_channels(channel_manager) {}
        
//         ~FriendServiceImpl() {}

//         /**
//          * @brief 获取好友列表
//          */
//         virtual void GetFriendList(::google::protobuf::RpcController* controller,
//             const ::mag::GetFriendListReq* request,
//             ::mag::GetFriendListRsp* response,
//             ::google::protobuf::Closure* done) override {
            
//             brpc::ClosureGuard rpc_guard(done); // 确保在函数结束时调用 done->Run()

//             // 定义错误回调函数
//             auto err_response = [this, response](const std::string &rid, 
//                 const std::string &errmsg) -> void {
//                 response->set_request_id(rid);
//                 response->set_success(false);
//                 response->set_errmsg(errmsg);
//                 return;
//             };

//             // 提取请求中的关键要素：请求ID和用户ID
//             std::string rid = request->request_id();
//             std::string uid = request->user_id();

//             // 从数据库中查询用户的好友ID列表
//             auto friend_id_lists = _mysql_relation->friends(uid);
//             std::unordered_set<std::string> user_id_lists(friend_id_lists.begin(), friend_id_lists.end());

//             // 从用户子服务批量获取用户信息
//             std::unordered_map<std::string, UserInfo> user_list;
//             bool ret = GetUserInfo(rid, user_id_lists, user_list);
//             if (!ret) {
//                 LOG_ERROR("{} - 批量获取用户信息失败!", rid);
//                 return err_response(rid, "批量获取用户信息失败!");
//             }

//             // 组织响应
//             response->set_request_id(rid);
//             response->set_success(true);
//             for (const auto &user_it : user_list) {
//                 auto user_info = response->add_friend_list();
//                 user_info->CopyFrom(user_it.second);
//             }
//         }

//         /**
//          * @brief 移除好友
//          */
//         virtual void FriendRemove(::google::protobuf::RpcController* controller,
//             const ::mag::FriendRemoveReq* request,
//             ::mag::FriendRemoveRsp* response,
//             ::google::protobuf::Closure* done) override {
            
//             brpc::ClosureGuard rpc_guard(done);

//             // 定义错误回调函数
//             auto err_response = [this, response](const std::string &rid, 
//                 const std::string &errmsg) -> void {
//                 response->set_request_id(rid);
//                 response->set_success(false);
//                 response->set_errmsg(errmsg);
//                 return;
//             };

//             // 提取请求中的关键要素：请求ID、用户ID、被移除的好友ID
//             std::string rid = request->request_id();
//             std::string uid = request->user_id();
//             std::string pid = request->peer_id();

//             // 从好友关系表中删除好友关系
//             bool ret = _mysql_relation->remove(uid, pid);
//             if (!ret) {
//                 LOG_ERROR("{} - 从数据库删除好友信息失败！", rid);
//                 return err_response(rid, "从数据库删除好友信息失败！");
//             }

//             // 从会话信息表中删除对应的聊天会话，并删除会话成员信息
//             ret = _mysql_chat_session->remove(uid, pid);
//             if (!ret) {
//                 LOG_ERROR("{}- 从数据库删除好友会话信息失败！", rid);
//                 return err_response(rid, "从数据库删除好友会话信息失败！");
//             }

//             // 组织响应
//             response->set_request_id(rid);
//             response->set_success(true);
//         }

//         /**
//          * @brief 添加好友申请
//          */
//         virtual void FriendAdd(::google::protobuf::RpcController* controller,
//             const ::mag::FriendAddReq* request,
//             ::mag::FriendAddRsp* response,
//             ::google::protobuf::Closure* done) override {
            
//             brpc::ClosureGuard rpc_guard(done);

//             // 定义错误回调函数
//             auto err_response = [this, response](const std::string &rid, 
//                 const std::string &errmsg) -> void {
//                 response->set_request_id(rid);
//                 response->set_success(false);
//                 response->set_errmsg(errmsg);
//                 return;
//             };

//             // 提取请求中的关键要素：请求ID、申请人ID、被申请人ID
//             std::string rid = request->request_id();
//             std::string uid = request->user_id();
//             std::string pid = request->respondent_id();

//             // 判断两人是否已经是好友
//             bool ret = _mysql_relation->exists(uid, pid);
//             if (ret) {
//                 LOG_ERROR("{}- 申请好友失败-两者{}-{}已经是好友关系", rid, uid, pid);
//                 return err_response(rid, "两者已经是好友关系！");
//             }

//             // 判断是否已经申请过好友
//             ret = _mysql_apply->exists(uid, pid);
//             if (ret) {
//                 LOG_ERROR("{}- 申请好友失败-已经申请过对方好友！", rid, uid, pid);
//                 return err_response(rid, "已经申请过对方好友！");
//             }

//             // 向好友申请表中新增申请信息
//             std::string eid = uuid();
//             FriendApply ev(eid, uid, pid);
//             ret = _mysql_apply->insert(ev);
//             if (!ret) {
//                 LOG_ERROR("{} - 向数据库新增好友申请事件失败！", rid);
//                 return err_response(rid, "向数据库新增好友申请事件失败！");
//             }

//             // 组织响应
//             response->set_request_id(rid);
//             response->set_success(true);
//             response->set_notify_event_id(eid);
//         }

//         /**
//          * @brief 处理好友申请
//          */
//         virtual void FriendAddProcess(::google::protobuf::RpcController* controller,
//             const ::mag::FriendAddProcessReq* request,
//             ::mag::FriendAddProcessRsp* response,
//             ::google::protobuf::Closure* done) override {
            
//             brpc::ClosureGuard rpc_guard(done);

//             // 定义错误回调函数
//             auto err_response = [this, response](const std::string &rid, 
//                 const std::string &errmsg) -> void {
//                 response->set_request_id(rid);
//                 response->set_success(false);
//                 response->set_errmsg(errmsg);
//                 return;
//             };

//             // 提取请求中的关键要素：请求ID、事件ID、被申请人ID、申请人ID、处理结果
//             std::string rid = request->request_id();
//             std::string eid = request->notify_event_id();
//             std::string uid = request->user_id();          // 被申请人
//             std::string pid = request->apply_user_id();    // 申请人
//             bool agree = request->agree();

//             // 判断是否存在该申请事件
//             bool ret = _mysql_apply->exists(pid, uid);
//             if (!ret) {
//                 LOG_ERROR("{}- 没有找到{}-{}对应的好友申请事件！", rid, pid, uid);
//                 return err_response(rid, "没有找到对应的好友申请事件!");
//             }

//             // 删除申请事件，标记事件已处理
//             ret = _mysql_apply->remove(pid, uid);
//             if (!ret) {
//                 LOG_ERROR("{}- 从数据库删除申请事件 {}-{} 失败！", rid, pid, uid);
//                 return err_response(rid, "从数据库删除申请事件失败!");
//             }

//             std::string cssid;
//             if (agree) {
//                 // 如果同意申请，新增好友关系
//                 ret = _mysql_relation->insert(uid, pid);
//                 if (!ret) {
//                     LOG_ERROR("{}- 新增好友关系信息-{}-{}！", rid, uid, pid);
//                     return err_response(rid, "新增好友关系信息!");
//                 }

//                 // 创建单聊会话
//                 cssid = uuid();
//                 ChatSession cs(cssid, "", ChatSessionType::SINGLE);
//                 ret = _mysql_chat_session->insert(cs);
//                 if (!ret) {
//                     LOG_ERROR("{}- 新增单聊会话信息-{}！", rid, cssid);
//                     return err_response(rid, "新增单聊会话信息失败!");
//                 }

//                 // 添加会话成员
//                 ChatSessionMember csm1(cssid, uid);
//                 ChatSessionMember csm2(cssid, pid);
//                 std::vector<ChatSessionMember> mlist = {csm1, csm2};
//                 ret = _mysql_chat_session_member->append(mlist);
//                 if (!ret) {
//                     LOG_ERROR("{}- 向会话添加成员失败！", rid, pid, uid);
//                     return err_response(rid, "向会话添加成员失败!");
//                 }
//             }

//             // 组织响应
//             response->set_request_id(rid);
//             response->set_success(true);
//             if (agree) {
//                 response->set_new_session_id(cssid);
//             }
//         }

//         /**
//          * @brief 搜索好友
//          */
//         virtual void FriendSearch(::google::protobuf::RpcController* controller,
//             const ::mag::FriendSearchReq* request,
//             ::mag::FriendSearchRsp* response,
//             ::google::protobuf::Closure* done) override {
            
//             brpc::ClosureGuard rpc_guard(done);

//             // 定义错误回调函数
//             auto err_response = [this, response](const std::string &rid, 
//                 const std::string &errmsg) -> void {
//                 response->set_request_id(rid);
//                 response->set_success(false);
//                 response->set_errmsg(errmsg);
//                 return;
//             };

//             // 提取请求中的关键要素：请求ID、用户ID、搜索关键字
//             std::string rid = request->request_id();
//             std::string uid = request->user_id();
//             std::string skey = request->search_key();
//             LOG_DEBUG("{} 好友搜索 ： {}", uid, skey);

//             // 根据用户ID，获取用户的好友ID列表
//             auto friend_id_lists = _mysql_relation->friends(uid);

//             // 从ES搜索引擎进行用户信息搜索，过滤掉当前的好友和自己
//             std::unordered_set<std::string> user_id_lists;
//             friend_id_lists.push_back(uid); // 过滤自己
//             auto search_res = _es_user->search(skey, friend_id_lists);
//             for (auto &it : search_res) {
//                 user_id_lists.insert(it.user_id());
//             }

//             // 从用户子服务批量获取用户信息
//             std::unordered_map<std::string, UserInfo> user_list;
//             bool ret = GetUserInfo(rid, user_id_lists, user_list);
//             if (!ret) {
//                 LOG_ERROR("{} - 批量获取用户信息失败!", rid);
//                 return err_response(rid, "批量获取用户信息失败!");
//             }

//             // 组织响应
//             response->set_request_id(rid);
//             response->set_success(true);
//             for (const auto &user_it : user_list) {
//                 auto user_info = response->add_user_info();
//                 user_info->CopyFrom(user_it.second);
//             }
//         }

//         /**
//          * @brief 获取待处理的好友申请事件列表
//          */
//         virtual void GetPendingFriendEventList(::google::protobuf::RpcController* controller,
//             const ::mag::GetPendingFriendEventListReq* request,
//             ::mag::GetPendingFriendEventListRsp* response,
//             ::google::protobuf::Closure* done) override {
            
//             brpc::ClosureGuard rpc_guard(done);

//             // 定义错误回调函数
//             auto err_response = [this, response](const std::string &rid, 
//                 const std::string &errmsg) -> void {
//                 response->set_request_id(rid);
//                 response->set_success(false);
//                 response->set_errmsg(errmsg);
//                 return;
//             };

//             // 提取请求中的关键要素：请求ID、用户ID
//             std::string rid = request->request_id();
//             std::string uid = request->user_id();

//             // 从数据库获取待处理的申请事件信息（申请人用户ID列表）
//             auto res = _mysql_apply->applyUsers(uid);
//             std::unordered_set<std::string> user_id_lists(res.begin(), res.end());

//             // 批量获取申请人用户信息
//             std::unordered_map<std::string, UserInfo> user_list;
//             bool ret = GetUserInfo(rid, user_id_lists, user_list);
//             if (!ret) {
//                 LOG_ERROR("{} - 批量获取用户信息失败!", rid);
//                 return err_response(rid, "批量获取用户信息失败!");
//             }

//             // 组织响应
//             response->set_request_id(rid);
//             response->set_success(true);
//             for (const auto &user_it : user_list) {
//                 auto ev = response->add_event();
//                 ev->mutable_sender()->CopyFrom(user_it.second);
//             }
//         }

//         /**
//          * @brief 获取聊天会话列表
//          */
//         virtual void GetChatSessionList(::google::protobuf::RpcController* controller,
//             const ::mag::GetChatSessionListReq* request,
//             ::mag::GetChatSessionListRsp* response,
//             ::google::protobuf::Closure* done) override {
            
//             brpc::ClosureGuard rpc_guard(done);

//             // 定义错误回调函数
//             auto err_response = [this, response](const std::string &rid, 
//                 const std::string &errmsg) -> void {
//                 response->set_request_id(rid);
//                 response->set_success(false);
//                 response->set_errmsg(errmsg);
//                 return;
//             };

//             // 提取请求中的关键要素：请求ID、用户ID
//             std::string rid = request->request_id();
//             std::string uid = request->user_id();

//             // 从数据库中查询用户的单聊会话列表
//             auto sf_list = _mysql_chat_session->singleChatSession(uid);

//             // 提取所有好友ID，准备批量获取用户信息
//             std::unordered_set<std::string> users_id_list;
//             for (const auto &f : sf_list) {
//                 users_id_list.insert(f.friend_id);
//             }

//             // 批量获取用户信息
//             std::unordered_map<std::string, UserInfo> user_list;
//             bool ret = GetUserInfo(rid, users_id_list, user_list);
//             if (!ret) {
//                 LOG_ERROR("{} - 批量获取用户信息失败！", rid);
//                 return err_response(rid, "批量获取用户信息失败!");
//             }

//             // 查询用户的群聊会话列表
//             auto gc_list = _mysql_chat_session->groupChatSession(uid);

//             // 组织单聊会话信息到响应
//             for (const auto &f : sf_list) {
//                 auto chat_session_info = response->add_chat_session_info_list();
//                 chat_session_info->set_single_chat_friend_id(f.friend_id);
//                 chat_session_info->set_chat_session_id(f.chat_session_id);
//                 chat_session_info->set_chat_session_name(user_list[f.friend_id].nickname());
//                 chat_session_info->set_avatar(user_list[f.friend_id].avatar());

//                 // 获取最近一条消息
//                 MessageInfo msg;
//                 ret = GetRecentMsg(rid, f.chat_session_id, msg);
//                 if (!ret) {
//                     continue; // 跳过无法获取消息的会话
//                 }
//                 chat_session_info->mutable_prev_message()->CopyFrom(msg);
//             }

//             // 组织群聊会话信息到响应
//             for (const auto &f : gc_list) {
//                 auto chat_session_info = response->add_chat_session_info_list();
//                 chat_session_info->set_chat_session_id(f.chat_session_id);
//                 chat_session_info->set_chat_session_name(f.chat_session_name());
//                 chat_session_info->set_avatar(f.avatar());

//                 // 获取最近一条消息
//                 MessageInfo msg;
//                 ret = GetRecentMsg(rid, f.chat_session_id, msg);
//                 if (!ret) {
//                     continue; // 跳过无法获取消息的会话
//                 }
//                 chat_session_info->mutable_prev_message()->CopyFrom(msg);
//             }

//             // 设置响应的其他字段
//             response->set_request_id(rid);
//             response->set_success(true);
//         }

//         /**
//          * @brief 创建聊天会话（群聊）
//          */
//         virtual void ChatSessionCreate(::google::protobuf::RpcController* controller,
//             const ::mag::ChatSessionCreateReq* request,
//             ::mag::ChatSessionCreateRsp* response,
//             ::google::protobuf::Closure* done) override {
            
//             brpc::ClosureGuard rpc_guard(done);

//             // 定义错误回调函数
//             auto err_response = [this, response](const std::string &rid, 
//                 const std::string &errmsg) -> void {
//                 response->set_request_id(rid);
//                 response->set_success(false);
//                 response->set_errmsg(errmsg);
//                 return;
//             };

//             // 提取请求中的关键要素：请求ID、用户ID、会话名称
//             std::string rid = request->request_id();
//             std::string uid = request->user_id();
//             std::string cssname = request->chat_session_name();

//             // 生成会话ID，向数据库添加会话信息
//             std::string cssid = uuid();
//             ChatSession cs(cssid, cssname, ChatSessionType::GROUP);
//             bool ret = _mysql_chat_session->insert(cs);
//             if (!ret) {
//                 LOG_ERROR("{} - 向数据库添加会话信息失败: {}", rid, cssname);
//                 return err_response(rid, "向数据库添加会话信息失败!");
//             }

//             // 添加会话成员信息
//             std::vector<ChatSessionMember> member_list;
//             for (int i = 0; i < request->member_id_list_size(); i++) {
//                 ChatSessionMember csm(cssid, request->member_id_list(i));
//                 member_list.push_back(csm);
//             }
//             ret = _mysql_chat_session_member->append(member_list);
//             if (!ret) {
//                 LOG_ERROR("{} - 向数据库添加会话成员信息失败: {}", rid, cssname);
//                 return err_response(rid, "向数据库添加会话成员信息失败!");
//             }

//             // 组织响应
//             response->set_request_id(rid);
//             response->set_success(true);
//             response->mutable_chat_session_info()->set_chat_session_id(cssid);
//             response->mutable_chat_session_info()->set_chat_session_name(cssname);
//         }

//         /**
//          * @brief 获取聊天会话成员信息
//          */
//         virtual void GetChatSessionMember(::google::protobuf::RpcController* controller,
//             const ::mag::GetChatSessionMemberReq* request,
//             ::mag::GetChatSessionMemberRsp* response,
//             ::google::protobuf::Closure* done) override {
            
//             brpc::ClosureGuard rpc_guard(done);

//             // 定义错误回调函数
//             auto err_response = [this, response](const std::string &rid, 
//                 const std::string &errmsg) -> void {
//                 response->set_request_id(rid);
//                 response->set_success(false);
//                 response->set_errmsg(errmsg);
//                 return;
//             };

//             // 提取请求中的关键要素：请求ID、用户ID、聊天会话ID
//             std::string rid = request->request_id();
//             std::string uid = request->user_id();
//             std::string cssid = request->chat_session_id();

//             // 从数据库获取会话成员ID列表
//             auto member_id_lists = _mysql_chat_session_member->members(cssid);
//             std::unordered_set<std::string> uid_list(member_id_lists.begin(), member_id_lists.end());

//             // 从用户子服务批量获取用户信息
//             std::unordered_map<std::string, UserInfo> user_list;
//             bool ret = GetUserInfo(rid, uid_list, user_list);
//             if (!ret) {
//                 LOG_ERROR("{} - 从用户子服务获取用户信息失败！", rid);
//                 return err_response(rid, "从用户子服务获取用户信息失败!");
//             }

//             // 组织响应
//             response->set_request_id(rid);
//             response->set_success(true);
//             for (const auto &uit : user_list) {
//                 auto user_info = response->add_member_info_list();
//                 user_info->CopyFrom(uit.second);
//             }
//         }

//     private:
//         /**
//          * @brief 获取最近一条消息
//          * 
//          * @param rid 请求ID
//          * @param cssid 会话ID
//          * @param msg 消息信息输出参数
//          * @return true 成功获取
//          * @return false 获取失败
//          */
//         bool GetRecentMsg(const std::string &rid, 
//             const std::string &cssid, MessageInfo &msg) {
            
//             // 获取消息存储子服务的信道
//             auto channel = _mm_channels->choose(_message_service_name);
//             if (!channel) {
//                 LOG_ERROR("{} - 获取消息子服务信道失败！！", rid);
//                 return false;
//             }

//             // 构造请求
//             GetRecentMsgReq req;
//             GetRecentMsgRsp rsp;
//             req.set_request_id(rid);
//             req.set_chat_session_id(cssid);
//             req.set_msg_count(1); // 获取最近一条消息

//             brpc::Controller cntl;
//             mag::MsgStorageService_Stub stub(channel.get());

//             // 调用消息存储子服务
//             stub.GetRecentMsg(&cntl, &req, &rsp, nullptr);
//             if (cntl.Failed()) {
//                 LOG_ERROR("{} - 消息存储子服务调用失败: {}", rid, cntl.ErrorText());
//                 return false;
//             }
//             if (!rsp.success()) {
//                 LOG_ERROR("{} - 获取会话 {} 最近消息失败: {}", rid, cssid, rsp.errmsg());
//                 return false;
//             }
//             if (rsp.msg_list_size() > 0) {
//                 msg.CopyFrom(rsp.msg_list(0));
//                 return true;
//             }
//             return false;
//         }

//         /**
//          * @brief 批量获取用户信息
//          * 
//          * @param rid 请求ID
//          * @param uid_list 用户ID集合
//          * @param user_list 用户信息输出参数
//          * @return true 成功获取
//          * @return false 获取失败
//          */
//         bool GetUserInfo(const std::string &rid, 
//             const std::unordered_set<std::string> &uid_list,
//             std::unordered_map<std::string, UserInfo> &user_list) {
            
//             // 获取用户子服务的信道
//             auto channel = _mm_channels->choose(_user_service_name);
//             if (!channel) {
//                 LOG_ERROR("{} - 获取用户子服务信道失败！！", rid);
//                 return false;
//             }

//             // 构造请求
//             GetMultiUserInfoReq req;
//             GetMultiUserInfoRsp rsp;
//             req.set_request_id(rid);
//             for (const auto &id : uid_list) {
//                 req.add_users_id(id);
//             }

//             brpc::Controller cntl;
//             mag::UserService_Stub stub(channel.get());

//             // 调用用户子服务
//             stub.GetMultiUserInfo(&cntl, &req, &rsp, nullptr);
//             if (cntl.Failed()) {
//                 LOG_ERROR("{} - 用户子服务调用失败: {}", rid, cntl.ErrorText());
//                 return false;
//             }
//             if (!rsp.success()) {
//                 LOG_ERROR("{} - 批量获取用户信息失败: {}", rid, rsp.errmsg());
//                 return false;
//             }

//             // 组织用户信息
//             for (const auto &user_it : rsp.users_info()) {
//                 user_list.emplace(user_it.first, user_it.second);
//             }
//             return true;
//         }

//     private:
//         // ES用户信息管理
//         ESUser::ptr _es_user;

//         // MySQL各个表的管理对象
//         FriendApplyTable::ptr _mysql_apply;
//         ChatSessionTable::ptr _mysql_chat_session;
//         ChatSessionMemeberTable::ptr _mysql_chat_session_member;
//         RelationTable::ptr _mysql_relation;

//         // RPC调用客户端相关对象
//         std::string _user_service_name;          // 用户子服务名称
//         std::string _message_service_name;       // 消息子服务名称
//         ServiceManager::ptr _mm_channels;        // 信道管理器
//     };

//     /**
//      * @brief FriendServer 类，负责搭建和启动RPC服务器
//      */
//     class FriendServer {
//     public:
//         using ptr = std::shared_ptr<FriendServer>;

//         /**
//          * @brief 构造函数，初始化各个组件
//          * 
//          * @param service_discoverer 服务发现客户端
//          * @param reg_client 服务注册客户端
//          * @param es_client ES客户端
//          * @param mysql_client MySQL客户端
//          * @param server RPC服务器实例
//          */
//         FriendServer(const Discovery::ptr service_discoverer, 
//             const Registry::ptr &reg_client,
//             const std::shared_ptr<elasticlient::Client> &es_client,
//             const std::shared_ptr<odb::core::database> &mysql_client,
//             const std::shared_ptr<brpc::Server> &server) :
//             _service_discoverer(service_discoverer),
//             _registry_client(reg_client),
//             _es_client(es_client),
//             _mysql_client(mysql_client),
//             _rpc_server(server) {}
        
//         ~FriendServer() {}

//         /**
//          * @brief 启动RPC服务器，进入运行状态
//          */
//         void start() {
//             _rpc_server->RunUntilAskedToQuit();
//         }

//     private:
//         Discovery::ptr _service_discoverer;                         // 服务发现客户端
//         Registry::ptr _registry_client;                             // 服务注册客户端
//         std::shared_ptr<elasticlient::Client> _es_client;           // ES客户端
//         std::shared_ptr<odb::core::database> _mysql_client;         // MySQL客户端
//         std::shared_ptr<brpc::Server> _rpc_server;                  // RPC服务器实例
//     };

//     /**
//      * @brief FriendServerBuilder 类，用于构建FriendServer实例
//      */
//     class FriendServerBuilder {
//     public:
//         /**
//          * @brief 构造ES客户端对象
//          * 
//          * @param host_list ES主机列表
//          */
//         void make_es_object(const std::vector<std::string> host_list) {
//             _es_client = ESClientFactory::create(host_list);
//         }

//         /**
//          * @brief 构造MySQL客户端对象
//          * 
//          * @param user MySQL用户名
//          * @param pswd MySQL密码
//          * @param host MySQL主机
//          * @param db MySQL数据库名
//          * @param cset MySQL字符集
//          * @param port MySQL端口
//          * @param conn_pool_count 连接池数量
//          */
//         void make_mysql_object(
//             const std::string &user,
//             const std::string &pswd,
//             const std::string &host,
//             const std::string &db,
//             const std::string &cset,
//             int port,
//             int conn_pool_count) {
//             _mysql_client = ODBFactory::create(user, pswd, host, db, cset, port, conn_pool_count);
//         }

//         /**
//          * @brief 构造服务发现客户端和信道管理对象
//          * 
//          * @param reg_host 服务注册主机
//          * @param base_service_name 基础服务名称
//          * @param user_service_name 用户子服务名称
//          * @param message_service_name 消息子服务名称
//          */
//         void make_discovery_object(const std::string &reg_host,
//             const std::string &base_service_name,
//             const std::string &user_service_name,
//             const std::string &message_service_name) {
            
//             _user_service_name = user_service_name;
//             _message_service_name = message_service_name;

//             // 初始化信道管理器
//             _mm_channels = std::make_shared<ServiceManager>();
//             _mm_channels->declared(user_service_name);
//             _mm_channels->declared(message_service_name);

//             LOG_DEBUG("设置用户子服务为需添加管理的子服务：{}", user_service_name);
//             LOG_DEBUG("设置消息子服务为需添加管理的子服务：{}", message_service_name);

//             // 绑定服务上线和下线回调
//             auto put_cb = std::bind(&ServiceManager::onServiceOnline, _mm_channels.get(), std::placeholders::_1, std::placeholders::_2);
//             auto del_cb = std::bind(&ServiceManager::onServiceOffline, _mm_channels.get(), std::placeholders::_1, std::placeholders::_2);

//             // 创建服务发现客户端
//             _service_discoverer = std::make_shared<Discovery>(reg_host, base_service_name, put_cb, del_cb);
//         }

//         /**
//          * @brief 构造服务注册客户端对象
//          * 
//          * @param reg_host 服务注册主机
//          * @param service_name 服务名称
//          * @param access_host 访问主机
//          */
//         void make_registry_object(const std::string &reg_host,
//             const std::string &service_name,
//             const std::string &access_host) {
//             _registry_client = std::make_shared<Registry>(reg_host);
//             _registry_client->registry(service_name, access_host);
//         }

//         /**
//          * @brief 构造并启动RPC服务器
//          * 
//          * @param port 监听端口
//          * @param timeout RPC超时时间（秒）
//          * @param num_threads RPC服务器线程数
//          */
//         void make_rpc_server(uint16_t port, int32_t timeout, uint8_t num_threads) {
//             // 检查各个模块是否已经初始化
//             if (!_es_client) {
//                 LOG_ERROR("还未初始化ES搜索引擎模块！");
//                 abort();
//             }
//             if (!_mysql_client) {
//                 LOG_ERROR("还未初始化Mysql数据库模块！");
//                 abort();
//             }
//             if (!_mm_channels) {
//                 LOG_ERROR("还未初始化信道管理模块！");
//                 abort();
//             }

//             // 创建RPC服务器实例
//             _rpc_server = std::make_shared<brpc::Server>();

//             // 创建FriendServiceImpl实例
//             FriendServiceImpl *friend_service = new FriendServiceImpl(_es_client,
//                 _mysql_client, _mm_channels, _user_service_name, _message_service_name);

//             // 添加服务到RPC服务器
//             int ret = _rpc_server->AddService(friend_service, 
//                 brpc::ServiceOwnership::SERVER_OWNS_SERVICE);
//             if (ret == -1) {
//                 LOG_ERROR("添加Rpc服务失败！");
//                 abort();
//             }

//             // 设置RPC服务器选项
//             brpc::ServerOptions options;
//             options.idle_timeout_sec = timeout;
//             options.num_threads = num_threads;

//             // 启动RPC服务器
//             ret = _rpc_server->Start(port, &options);
//             if (ret == -1) {
//                 LOG_ERROR("服务启动失败！");
//                 abort();
//             }
//         }

//         /**
//          * @brief 构建FriendServer实例
//          * 
//          * @return FriendServer::ptr 构建好的FriendServer实例
//          */
//         FriendServer::ptr build() {
//             // 检查服务发现和注册模块是否已初始化
//             if (!_service_discoverer) {
//                 LOG_ERROR("还未初始化服务发现模块！");
//                 abort();
//             }
//             if (!_registry_client) {
//                 LOG_ERROR("还未初始化服务注册模块！");
//                 abort();
//             }
//             if (!_rpc_server) {
//                 LOG_ERROR("还未初始化RPC服务器模块！");
//                 abort();
//             }

//             // 创建FriendServer实例
//             FriendServer::ptr server = std::make_shared<FriendServer>(
//                 _service_discoverer, _registry_client,
//                 _es_client, _mysql_client, _rpc_server);
//             return server;
//         }

//     private:
//         Registry::ptr _registry_client;                           // 服务注册客户端
//         std::shared_ptr<elasticlient::Client> _es_client;         // ES客户端
//         std::shared_ptr<odb::core::database> _mysql_client;       // MySQL客户端

//         std::string _user_service_name;                           // 用户子服务名称
//         std::string _message_service_name;                        // 消息子服务名称
//         ServiceManager::ptr _mm_channels;                         // 信道管理器
//         Discovery::ptr _service_discoverer;                       // 服务发现客户端

//         std::shared_ptr<brpc::Server> _rpc_server;                // RPC服务器实例
//     };

// } // namespace mag














//////////////////////////////////////////////////////////////////////////////////////////////////
// #include <brpc/server.h>
// #include <butil/logging.h>

// #include "data_es.hpp"      // es数据管理客户端封装
// #include "mysql_chat_session_member.hpp"      // mysql数据管理客户端封装
// #include "mysql_chat_session.hpp"      // mysql数据管理客户端封装
// #include "mysql_relation.hpp"      // mysql数据管理客户端封装
// #include "mysql_apply.hpp"      // mysql数据管理客户端封装
// #include "etcd.hpp"     // 服务注册模块封装
// #include "logger.hpp"   // 日志模块封装
// #include "utils.hpp"    // 基础工具接口
// #include "channel.hpp"  // 信道管理模块封装


// #include "friend.pb.h"  // protobuf框架代码
// #include "base.pb.h"  // protobuf框架代码
// #include "user.pb.h"  // protobuf框架代码
// #include "message.pb.h"  // protobuf框架代码

// namespace mag
// {
// class FriendServiceImpl : public mag::FriendService {
//     public:
//         FriendServiceImpl(
//             const std::shared_ptr<elasticlient::Client> &es_client,
//             const std::shared_ptr<odb::core::database> &mysql_client,
//             const ServiceManager::ptr &channel_manager,
//             const std::string &user_service_name,
//             const std::string &message_service_name) :
//             _es_user(std::make_shared<ESUser>(es_client)),
//             _mysql_apply(std::make_shared<FriendApplyTable>(mysql_client)),
//             _mysql_chat_session(std::make_shared<ChatSessionTable>(mysql_client)),
//             _mysql_chat_session_member(std::make_shared<ChatSessionMemeberTable>(mysql_client)),
//             _mysql_relation(std::make_shared<RelationTable>(mysql_client)),
//             _user_service_name(user_service_name),
//             _message_service_name(message_service_name),
//             _mm_channels(channel_manager){}
//         ~FriendServiceImpl(){}

//         ///////////////////////////////////////////////////////
//         ///获取用户的好友列表
//         //////////////////////////////////////////////////////
//         virtual void GetFriendList(::google::protobuf::RpcController* controller,
//             const ::mag::GetFriendListReq* request,
//             ::mag::GetFriendListRsp* response,
//             ::google::protobuf::Closure* done){
//                 brpc::ClosureGuard rpc_guard(done);
//                 //1. 定义错误回调
//                 auto err_response = [this, response](const std::string &rid, 
//                     const std::string &errmsg) -> void {
//                     response->set_request_id(rid);
//                     response->set_success(false);
//                     response->set_errmsg(errmsg);
//                     return;
//                 };
                
//                 //1. 提取请求中的关键要素：用户ID
//                 std::string rid = request->request_id();
//                 std::string uid = request->user_id();
//                 //2. 从数据库中查询获取用户的好友ID
//                 auto friend_id_lists = _mysql_relation->friends(uid);
//                 std::unordered_set<std::string> user_id_lists;
//                 for (auto &id : friend_id_lists) {
//                     user_id_lists.insert(id);
//                 }
//                 //3. 从用户子服务批量获取用户信息
//                 std::unordered_map<std::string, UserInfo> user_list;
//                 bool ret = GetUserInfo(rid, user_id_lists, user_list);
//                 if (ret == false) {
//                     LOG_ERROR("{} - 批量获取用户信息失败!", rid);
//                     return err_response(rid, "批量获取用户信息失败!");
//                 }
//                 //4. 组织响应
//                 response->set_request_id(rid);
//                 response->set_success(true);
//                 for (const auto & user_it : user_list) {
//                     auto user_info = response->add_friend_list();
//                     user_info->CopyFrom(user_it.second);
//                 }
//             }

//         ///////////////////////////////////////////////////////
//         ///移除好友
//         //////////////////////////////////////////////////////
//         virtual void FriendRemove(::google::protobuf::RpcController* controller,
//             const ::mag::FriendRemoveReq* request,
//             ::mag::FriendRemoveRsp* response,
//             ::google::protobuf::Closure* done){
//                 brpc::ClosureGuard rpc_guard(done);
//                 //1. 定义错误回调
//                 auto err_response = [this, response](const std::string &rid, 
//                     const std::string &errmsg) -> void {
//                     response->set_request_id(rid);
//                     response->set_success(false);
//                     response->set_errmsg(errmsg);
//                     return;
//                 };
//                 //1. 提取关键要素：当前用户ID，要删除的好友ID
//                 std::string rid = request->request_id();
//                 std::string uid = request->user_id();
//                 std::string pid = request->peer_id();
//                 //2. 从好友关系表中删除好友关系信息
//                 bool ret = _mysql_relation->remove(uid, pid);
//                 if (ret == false) {
//                     LOG_ERROR("{} - 从数据库删除好友信息失败！", rid);
//                     return err_response(rid, "从数据库删除好友信息失败！");
//                 }
//                 //3. 从会话信息表中，删除对应的聊天会话 -- 同时删除会话成员表中的成员信息
//                 ret = _mysql_chat_session->remove(uid, pid);
//                 if (ret == false) {
//                     LOG_ERROR("{}- 从数据库删除好友会话信息失败！", rid);
//                     return err_response(rid, "从数据库删除好友会话信息失败！");
//                 }
//                 //4. 组织响应
//                 response->set_request_id(rid);
//                 response->set_success(true);
//             }

//         ///////////////////////////////////////////////////////
//         ///添加好友
//         //////////////////////////////////////////////////////
//         virtual void FriendAdd(::google::protobuf::RpcController* controller,
//             const ::mag::FriendAddReq* request,
//             ::mag::FriendAddRsp* response,
//             ::google::protobuf::Closure* done){
//                 brpc::ClosureGuard rpc_guard(done);
//                 //1. 定义错误回调
//                 auto err_response = [this, response](const std::string &rid, 
//                     const std::string &errmsg) -> void {
//                     response->set_request_id(rid);
//                     response->set_success(false);
//                     response->set_errmsg(errmsg);
//                     return;
//                 };
//                 //1. 提取请求中的关键要素：申请人用户ID； 被申请人用户ID
//                 std::string rid = request->request_id();
//                 std::string uid = request->user_id();
//                 std::string pid = request->respondent_id();//被申请人用户ID
//                 //2. 判断两人是否已经是好友
//                 bool ret = _mysql_relation->exists(uid, pid);
//                 if (ret == true) {
//                     LOG_ERROR("{}- 申请好友失败-两者{}-{}已经是好友关系", rid, uid, pid);
//                     return err_response(rid, "两者已经是好友关系！");
//                 }
//                 //3. 当前是否已经申请过好友
//                 ret = _mysql_apply->exists(uid, pid);
//                 if (ret == true) {
//                     LOG_ERROR("{}- 申请好友失败-已经申请过对方好友！", rid, uid, pid);
//                     return err_response(rid, "已经申请过对方好友！");
//                 }
//                 //4. 向好友申请表中，新增申请信息
//                 std::string eid = uuid();
//                 FriendApply ev(eid, uid, pid);
//                 ret = _mysql_apply->insert(ev);
//                 if (ret == false) {
//                     LOG_ERROR("{} - 向数据库新增好友申请事件失败！", rid);
//                     return err_response(rid, "向数据库新增好友申请事件失败！");
//                 }
//                 //3. 组织响应
//                 response->set_request_id(rid);
//                 response->set_success(true);
//                 response->set_notify_event_id(eid); 
//             }

//         ///////////////////////////////////////////////////////
//         ///处理好友申请
//         //////////////////////////////////////////////////////
//         virtual void FriendAddProcess(::google::protobuf::RpcController* controller,
//             const ::mag::FriendAddProcessReq* request,
//             ::mag::FriendAddProcessRsp* response,
//             ::google::protobuf::Closure* done){
//                 brpc::ClosureGuard rpc_guard(done);
//                 //1. 定义错误回调
//                 auto err_response = [this, response](const std::string &rid, 
//                     const std::string &errmsg) -> void {
//                     response->set_request_id(rid);
//                     response->set_success(false);
//                     response->set_errmsg(errmsg);
//                     return;
//                 };
//                 //1. 提取请求中的关键要素：申请人用户ID；被申请人用户ID；处理结果；事件ID
//                 std::string rid = request->request_id();
//                 std::string eid = request->notify_event_id();
//                 std::string uid = request->user_id(); //被申请人
//                 std::string pid = request->apply_user_id();//申请人
//                 bool agree = request->agree();
//                 //2. 判断有没有该申请事件
//                 bool ret = _mysql_apply->exists(pid, uid);
//                 if (ret == false) {
//                     LOG_ERROR("{}- 没有找到{}-{}对应的好友申请事件！", rid, pid, uid);
//                     return err_response(rid, "没有找到对应的好友申请事件!");
//                 }
//                 //3. 如果有： 可以处理； --- 删除申请事件--事件已经处理完毕
//                 ret = _mysql_apply->remove(pid, uid);
//                 if (ret == false) {
//                     LOG_ERROR("{}- 从数据库删除申请事件 {}-{} 失败！", rid, pid, uid);
//                     return err_response(rid, "从数据库删除申请事件失败!");
//                 }
//                 //4. 如果处理结果是同意：向数据库新增好友关系信息；新增单聊会话信息及会话成员
//                 std::string cssid;
//                 if (agree == true) {
//                     ret = _mysql_relation->insert(uid, pid);
//                     if (ret == false) {
//                         LOG_ERROR("{}- 新增好友关系信息-{}-{}！", rid, uid, pid);
//                         return err_response(rid, "新增好友关系信息!");
//                     }
//                     cssid = uuid();
//                     ChatSession cs(cssid, "", ChatSessionType::SINGLE);
//                     ret = _mysql_chat_session->insert(cs);
//                     if (ret == false) {
//                         LOG_ERROR("{}- 新增单聊会话信息-{}！", rid, cssid);
//                         return err_response(rid, "新增单聊会话信息失败!");
//                     }
//                     ChatSessionMember csm1(cssid, uid);
//                     ChatSessionMember csm2(cssid, pid);
//                     std::vector<ChatSessionMember> mlist = {csm1, csm2};
//                     ret = _mysql_chat_session_member->append(mlist);
//                     if (ret == false) {
//                         LOG_ERROR("{}- 没有找到{}-{}对应的好友申请事件！", rid, pid, uid);
//                         return err_response(rid, "没有找到对应的好友申请事件!");
//                     }
//                 }
//                 //5. 组织响应
//                 response->set_request_id(rid);
//                 response->set_success(true);
//                 response->set_new_session_id(cssid);
//             }

//         ///////////////////////////////////////////////////////
//         ///根据关键字搜索朋友
//         //////////////////////////////////////////////////////
//         virtual void FriendSearch(::google::protobuf::RpcController* controller,
//             const ::mag::FriendSearchReq* request,
//             ::mag::FriendSearchRsp* response,
//             ::google::protobuf::Closure* done){
//                 brpc::ClosureGuard rpc_guard(done);
//                 //1. 定义错误回调
//                 auto err_response = [this, response](const std::string &rid, 
//                     const std::string &errmsg) -> void {
//                     response->set_request_id(rid);
//                     response->set_success(false);
//                     response->set_errmsg(errmsg);
//                     return;
//                 };

//                 //2. 提取请求关键信息
//                 std::string rid = request->request_id();
//                 std::string uid = request->user_id();
//                 std::string skey = request->search_key();
//                 LOG_DEBUG("{} 好友搜索 ： {}", uid, skey);

//                 //3. 根据用户ID，获取好友ID列表
//                 auto friend_id_lists = _mysql_relation->friends(uid);

//                 //4. 从ES中进行用户信息搜索，过滤掉当前的好友
//                 std::unordered_set<std::string> user_id_lists;
//                 friend_id_lists.push_back(uid);// 把自己也过滤掉
//                 auto search_res = _es_user->search(skey, friend_id_lists);
//                 for (auto &it : search_res) {
//                     user_id_lists.insert(it.user_id());
//                 }

//                 //5. 获取获取的用户ID，从用户子服务器中获取用户信息
//                 std::unordered_map<std::string, UserInfo> user_list;
//                 bool ret = GetUserInfo(rid, user_id_lists, user_list);
//                 if (ret == false) {
//                     LOG_ERROR("{} - 批量获取用户信息失败!", rid);
//                     return err_response(rid, "批量获取用户信息失败!");
//                 }

//                 //6. 组织响应
//                 response->set_request_id(rid);
//                 response->set_success(true);
//                 for (const auto & user_it : user_list) {
//                     auto user_info = response->add_user_info();
//                     user_info->CopyFrom(user_it.second);
//                 }
//             }

//         ///////////////////////////////////////////////////////
//         ///获取当前用户的待处理好友申请事件列表
//         //////////////////////////////////////////////////////
//         virtual void GetPendingFriendEventList(::google::protobuf::RpcController* controller,
//             const ::mag::GetPendingFriendEventListReq* request,
//             ::mag::GetPendingFriendEventListRsp* response,
//             ::google::protobuf::Closure* done){
//                 brpc::ClosureGuard rpc_guard(done);
//                 //1. 定义错误回调
//                 auto err_response = [this, response](const std::string &rid, 
//                     const std::string &errmsg) -> void {
//                     response->set_request_id(rid);
//                     response->set_success(false);
//                     response->set_errmsg(errmsg);
//                     return;
//                 };

//                 //2. 提取关键要素：当前用户ID
//                 std::string rid = request->request_id();
//                 std::string uid = request->user_id();

//                 //3. 从数据库获取待处理的申请事件信息 --- 申请人用户ID列表
//                 auto res = _mysql_apply->applyUsers(uid);
//                 std::unordered_set<std::string> user_id_lists;
//                 for (auto &id : res) {
//                     user_id_lists.insert(id);
//                 }

//                 //4. 批量获取申请人信息
//                 std::unordered_map<std::string, UserInfo> user_list;
//                 bool ret = GetUserInfo(rid, user_id_lists, user_list);
//                 if (ret == false) {
//                     LOG_ERROR("{} - 批量获取用户信息失败!", rid);
//                     return err_response(rid, "批量获取用户信息失败!");
//                 }

//                 //5. 组织响应
//                 response->set_request_id(rid);
//                 response->set_success(true);
//                 for (const auto & user_it : user_list) {
//                     auto ev = response->add_event();
//                     ev->mutable_sender()->CopyFrom(user_it.second);
//                 }
//             }

//         ///////////////////////////////////////////////////////
//         ///获取当前用户的聊天会话列表（包括单聊和群聊）
//         //////////////////////////////////////////////////////
//         virtual void GetChatSessionList(::google::protobuf::RpcController* controller,
//             const ::mag::GetChatSessionListReq* request,
//             ::mag::GetChatSessionListRsp* response,
//             ::google::protobuf::Closure* done){
//                 brpc::ClosureGuard rpc_guard(done);
//                 //1. 定义错误回调
//                 auto err_response = [this, response](const std::string &rid, 
//                     const std::string &errmsg) -> void {
//                     response->set_request_id(rid);
//                     response->set_success(false);
//                     response->set_errmsg(errmsg);
//                     return;
//                 };

//                 //2. 提取请求关键字段
//                 std::string rid = request->request_id();  // 请求的唯一 ID
//                 std::string uid = request->user_id();     // 当前请求用户的 ID

//                 //3. 查询用户单聊会话列表
//                 auto sf_list = _mysql_chat_session->singleChatSession(uid);

//                 //4. 从单聊会话列表中获取所有的好友ID，并获取好友的用户信息
//                 std::unordered_set<std::string> users_id_list;
//                 for (const auto &f : sf_list) {
//                     users_id_list.insert(f.friend_id);
//                 }
//                 std::unordered_map<std::string, UserInfo> user_list;
//                 //4.1 批量获取好友的用户信息
//                 bool ret = GetUserInfo(rid, users_id_list, user_list);
//                 if (ret == false) {
//                     LOG_ERROR("{} - 批量获取用户信息失败！", rid);
//                     return err_response(rid, "批量获取用户信息失败!");
//                 }

//                 //5. 设置单聊会话的响应信息
//                 for (const auto &f : sf_list) {
//                 auto chat_session_info = response->add_chat_session_info_list();
//                 chat_session_info->set_single_chat_friend_id(f.friend_id);
//                 chat_session_info->set_chat_session_id(f.chat_session_id);
//                 chat_session_info->set_chat_session_name(user_list[f.friend_id].nickname());
//                 chat_session_info->set_avatar(user_list[f.friend_id].avatar());
//                 MessageInfo msg;
//                 ret = GetRecentMsg(rid, f.chat_session_id, msg);
//                 if (ret == false) { continue; }
//                 chat_session_info->mutable_prev_message()->CopyFrom(msg);
//                 }

//                 //6. 查询用户的群聊会话列表
//                 auto gc_list = _mysql_chat_session->groupChatSession(uid);

//                 //7. 设置群聊会话的响应信息
//                 for (const auto &f : gc_list) {
//                 auto chat_session_info = response->add_chat_session_info_list();
//                 chat_session_info->set_chat_session_id(f.chat_session_id);
//                 chat_session_info->set_chat_session_name(f.chat_session_name);
//                 MessageInfo msg;
//                 ret = GetRecentMsg(rid, f.chat_session_id, msg);
//                 if (ret == false) { continue; }
//                 chat_session_info->mutable_prev_message()->CopyFrom(msg);
//                 }

//                 //8. 最终响应
//                 response->set_request_id(rid);
//                 response->set_success(true);
//             }

//         ///////////////////////////////////////////////////////
//         ///创建一个群聊会话
//         //////////////////////////////////////////////////////
//         virtual void ChatSessionCreate(::google::protobuf::RpcController* controller,
//             const ::mag::ChatSessionCreateReq* request,
//             ::mag::ChatSessionCreateRsp* response,
//             ::google::protobuf::Closure* done){
//                 brpc::ClosureGuard rpc_guard(done);
//                 //1. 定义错误回调
//                 auto err_response = [this, response](const std::string &rid, 
//                     const std::string &errmsg) -> void {
//                     response->set_request_id(rid);
//                     response->set_success(false);
//                     response->set_errmsg(errmsg);
//                     return;
//                 };
                
//                 //2. 提取请求中的信息
//                 std::string rid = request->request_id();
//                 std::string uid = request->user_id();
//                 std::string cssname = request->chat_session_name();

//                 //3. 生成会话ID，向数据库中添加会话信息以及会话成员信息
//                 std::string cssid = uuid();
//                 ChatSession cs(cssid, cssname, ChatSessionType::GROUP);
//                 bool ret = _mysql_chat_session->insert(cs);
//                 if (ret == false) {
//                     LOG_ERROR("{} - 向数据库添加会话信息失败: {}", rid, cssname);
//                     return err_response(rid, "向数据库添加会话信息失败!");
//                 }

//                 std::vector<ChatSessionMember> member_list;
//                 for (int i = 0; i < request->member_id_list_size(); i++) {
//                     ChatSessionMember csm(cssid, request->member_id_list(i));
//                     member_list.push_back(csm);
//                 }
//                 ret = _mysql_chat_session_member->append(member_list);
//                 if (ret == false) {
//                     LOG_ERROR("{} - 向数据库添加会话成员信息失败: {}", rid, cssname);
//                     return err_response(rid, "向数据库添加会话成员信息失败!");
//                 }

//                 //4. 组织响应
//                 response->set_request_id(rid);
//                 response->set_success(true);
//                 response->mutable_chat_session_info()->set_chat_session_id(cssid);
//                 response->mutable_chat_session_info()->set_chat_session_name(cssname);

//             }

//         ///////////////////////////////////////////////////////
//         ///获取群聊会话的成员信息
//         //////////////////////////////////////////////////////
//         virtual void GetChatSessionMember(::google::protobuf::RpcController* controller,
//             const ::mag::GetChatSessionMemberReq* request,
//             ::mag::GetChatSessionMemberRsp* response,
//             ::google::protobuf::Closure* done){

//                 brpc::ClosureGuard rpc_guard(done);
//                 auto err_response = [this, response](const std::string &rid, 
//                     const std::string &errmsg) -> void {
//                     response->set_request_id(rid);
//                     response->set_success(false);
//                     response->set_errmsg(errmsg);
//                     return;
//                 };

//                 //1. 提取关键要素：聊天会话ID
//                 std::string rid = request->request_id();
//                 std::string uid = request->user_id();
//                 std::string cssid = request->chat_session_id();

//                 //2. 获取回话成员List列表
//                 auto member_id_lists = _mysql_chat_session_member->members(cssid);
//                 std::unordered_set<std::string> uid_list;
//                 for (const auto &id : member_id_lists) {
//                     uid_list.insert(id);
//                 }

//                 //3. 从用户子服务中批量获取用户信息
//                 std::unordered_map<std::string, UserInfo> user_list;
//                 bool ret = GetUserInfo(rid, uid_list, user_list);
//                 if (ret == false) {
//                     LOG_ERROR("{} - 从用户子服务获取用户信息失败！", rid);
//                     return err_response(rid, "从用户子服务获取用户信息失败!");
//                 }

//                 //4. 组织响应
//                 response->set_request_id(rid);
//                 response->set_success(true);
//                 for (const auto &uit : user_list) {
//                     auto user_info = response->add_member_info_list();
//                     user_info->CopyFrom(uit.second);
//                 }
//             }

//     private:
//         ///////////////////////////////////////////////////
//         ///获取最近的消息
//         /////////////////////////////////////////////////
//         bool GetRecentMsg(const std::string &rid, 
//                   const std::string &cssid, 
//                   MessageInfo &msg) {
//                     // 选择消息服务信道
//                     auto channel = _mm_channels->choose(_message_service_name);
//                     if (!channel) {
//                         // 获取信道失败，记录错误日志
//                         LOG_ERROR("{} - 获取消息子服务信道失败！！", rid);
//                         return false;
//                     }

//                     // 设置获取消息的请求
//                     GetRecentMsgReq req;
//                     GetRecentMsgRsp rsp;
//                     req.set_request_id(rid);  // 设置请求ID
//                     req.set_chat_session_id(cssid);  // 设置聊天会话ID
//                     req.set_msg_count(1);  // 设置获取的消息数量为1
//                     brpc::Controller cntl;  // 设置控制器
//                     mag::MsgStorageService_Stub stub(channel.get());  // 创建消息存储服务的存根
//                     stub.GetRecentMsg(&cntl, &req, &rsp, nullptr);  // 调用消息存储服务的 GetRecentMsg 方法

//                     // 检查请求是否失败
//                     if (cntl.Failed() == true) {
//                         LOG_ERROR("{} - 消息存储子服务调用失败: {}", rid, cntl.ErrorText());
//                         return false;
//                     }

//                     // 检查响应是否成功
//                     if (rsp.success() == false) {
//                         LOG_ERROR("{} - 获取会话 {} 最近消息失败: {}", rid, cssid, rsp.errmsg());
//                         return false;
//                     }

//                     // 如果返回的消息列表不为空，将第一个消息复制到 msg 中
//                     if (rsp.msg_list_size() > 0) {
//                         msg.CopyFrom(rsp.msg_list(0));
//                         return true;
//                     }

//                     // 如果消息列表为空，返回 false
//                     return false;
//                 }

//         ///////////////////////////////////////////////////
//         ///批量获取用户信息
//         /////////////////////////////////////////////////
//         bool GetUserInfo(const std::string &rid, 
//                  const std::unordered_set<std::string> &uid_list,
//                  std::unordered_map<std::string, UserInfo> &user_list) {
//                 // 选择用户服务信道
//                 auto channel = _mm_channels->choose(_user_service_name);
//                 if (!channel) {
//                     // 获取信道失败，记录错误日志
//                     LOG_ERROR("{} - 获取用户子服务信道失败！！", rid);
//                     return false;
//                 }

//                 // 设置批量获取用户信息的请求
//                 GetMultiUserInfoReq req;
//                 GetMultiUserInfoRsp rsp;
//                 req.set_request_id(rid);  // 设置请求ID
//                 for (auto &id : uid_list) {
//                     req.add_users_id(id);  // 将每个用户ID添加到请求中
//                 }

//                 brpc::Controller cntl;  // 设置控制器
//                 mag::UserService_Stub stub(channel.get());  // 创建用户服务的存根
//                 stub.GetMultiUserInfo(&cntl, &req, &rsp, nullptr);  // 调用用户服务的 GetMultiUserInfo 方法

//                 // 检查请求是否失败
//                 if (cntl.Failed() == true) {
//                     LOG_ERROR("{} - 用户子服务调用失败: {}", rid, cntl.ErrorText());
//                     return false;
//                 }

//                 // 检查响应是否成功
//                 if (rsp.success() == false) {
//                     LOG_ERROR("{} - 批量获取用户信息失败: {}", rid, rsp.errmsg());
//                     return false;
//                 }

//                 // 将返回的用户信息添加到 user_list 中
//                 for (const auto &user_it : rsp.users_info()) {
//                     user_list.insert(std::make_pair(user_it.first, user_it.second));  // 插入用户ID和对应的信息
//                 }

//                 return true;
//             }
    
//     private:
//         ESUser::ptr _es_user;

//         FriendApplyTable::ptr _mysql_apply;
//         ChatSessionTable::ptr _mysql_chat_session;
//         ChatSessionMemeberTable::ptr _mysql_chat_session_member;
//         RelationTable::ptr _mysql_relation;

//         //这边是rpc调用客户端相关对象
//         std::string _user_service_name;
//         std::string _message_service_name;
//         ServiceManager::ptr _mm_channels; 

// };

// class FriendServer {
//     public:
//         using ptr = std::shared_ptr<FriendServer>;
//         FriendServer(const Discovery::ptr service_discoverer, 
//             const Registry::ptr &reg_client,
//             const std::shared_ptr<elasticlient::Client> &es_client,
//             const std::shared_ptr<odb::core::database> &mysql_client,
//             const std::shared_ptr<brpc::Server> &server):
//             _service_discoverer(service_discoverer),
//             _registry_client(reg_client),
//             _es_client(es_client),
//             _mysql_client(mysql_client),
//             _rpc_server(server){}
//         ~FriendServer(){}
//         //搭建RPC服务器，并启动服务器
//         void start() {
//             _rpc_server->RunUntilAskedToQuit();
//         }
//     private:
//         Discovery::ptr _service_discoverer;
//         Registry::ptr _registry_client;
//         std::shared_ptr<elasticlient::Client> _es_client;
//         std::shared_ptr<odb::core::database> _mysql_client;
//         std::shared_ptr<brpc::Server> _rpc_server;
// };

// class FriendServerBuilder {
//     public:
//         //构造es客户端对象
//         void make_es_object(const std::vector<std::string> host_list) {
//             _es_client = ESClientFactory::create(host_list);
//         }
//         //构造mysql客户端对象
//         void make_mysql_object(
//             const std::string &user,
//             const std::string &pswd,
//             const std::string &host,
//             const std::string &db,
//             const std::string &cset,
//             int port,
//             int conn_pool_count) {
//             _mysql_client = ODBFactory::create(user, pswd, host, db, cset, port, conn_pool_count);
//         }
//         //用于构造服务发现客户端&信道管理对象
//         void make_discovery_object(const std::string &reg_host,
//             const std::string &base_service_name,
//             const std::string &user_service_name,
//             const std::string &message_service_name) {
//             _user_service_name = user_service_name;
//             _message_service_name = message_service_name;
//             _mm_channels = std::make_shared<ServiceManager>();
//             _mm_channels->declared(user_service_name);
//             _mm_channels->declared(message_service_name);
//             LOG_DEBUG("设置用户子服务为需添加管理的子服务：{}", user_service_name);
//             LOG_DEBUG("设置消息子服务为需添加管理的子服务：{}", message_service_name);
//             auto put_cb = std::bind(&ServiceManager::onServiceOnline, _mm_channels.get(), std::placeholders::_1, std::placeholders::_2);
//             auto del_cb = std::bind(&ServiceManager::onServiceOffline, _mm_channels.get(), std::placeholders::_1, std::placeholders::_2);
//             _service_discoverer = std::make_shared<Discovery>(reg_host, base_service_name, put_cb, del_cb);
//         }
//         //用于构造服务注册客户端对象
//         void make_registry_object(const std::string &reg_host,
//             const std::string &service_name,
//             const std::string &access_host) {
//             _registry_client = std::make_shared<Registry>(reg_host);
//             _registry_client->registry(service_name, access_host);
//         }
//         void make_rpc_server(uint16_t port, int32_t timeout, uint8_t num_threads) {
//             if (!_es_client) {
//                 LOG_ERROR("还未初始化ES搜索引擎模块！");
//                 abort();
//             }
//             if (!_mysql_client) {
//                 LOG_ERROR("还未初始化Mysql数据库模块！");
//                 abort();
//             }
//             if (!_mm_channels) {
//                 LOG_ERROR("还未初始化信道管理模块！");
//                 abort();
//             }
//             _rpc_server = std::make_shared<brpc::Server>();

//             FriendServiceImpl *friend_service = new FriendServiceImpl(_es_client,
//                 _mysql_client, _mm_channels, _user_service_name, _message_service_name);
//             int ret = _rpc_server->AddService(friend_service, 
//                 brpc::ServiceOwnership::SERVER_OWNS_SERVICE);
//             if (ret == -1) {
//                 LOG_ERROR("添加Rpc服务失败！");
//                 abort();
//             }
//             brpc::ServerOptions options;
//             options.idle_timeout_sec = timeout;
//             options.num_threads = num_threads;
//             ret = _rpc_server->Start(port, &options);
//             if (ret == -1) {
//                 LOG_ERROR("服务启动失败！");
//                 abort();
//             }
//         }
//         //构造RPC服务器对象
//         FriendServer::ptr build() {
//             if (!_service_discoverer) {
//                 LOG_ERROR("还未初始化服务发现模块！");
//                 abort();
//             }
//             if (!_registry_client) {
//                 LOG_ERROR("还未初始化服务注册模块！");
//                 abort();
//             }
//             if (!_rpc_server) {
//                 LOG_ERROR("还未初始化RPC服务器模块！");
//                 abort();
//             }
//             FriendServer::ptr server = std::make_shared<FriendServer>(
//                 _service_discoverer, _registry_client,
//                 _es_client, _mysql_client, _rpc_server);
//             return server;
//         }
//     private:
//         Registry::ptr _registry_client;

//         std::shared_ptr<elasticlient::Client> _es_client;
//         std::shared_ptr<odb::core::database> _mysql_client;

//         std::string _user_service_name;
//         std::string _message_service_name;
//         ServiceManager::ptr _mm_channels;
//         Discovery::ptr _service_discoverer;

//         std::shared_ptr<brpc::Server> _rpc_server;
// };

// }